home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / AOCE / Development Tools / Sample Code / Messaging Service Access Module / Internet PMSAM / Internet PMSAM source / spoolsystem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-05  |  8.8 KB  |  438 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------
  2.  
  3. AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
  4. Mail Service Access Module
  5.  
  6. written by Steve Falkenburg-- MacDTS
  7. ©1991-1993 Apple Computer, Inc.
  8.  
  9. --------------
  10. change history
  11. --------------
  12.  
  13. SJF        02/19/93    update for beta build    b1
  14. SJF        10/29/92    update to a11            a11
  15. SJF        06/08/92    update to a8            a8
  16. SJF        02/15/92    first working version    a4.5
  17. SJF        10/16/91    initial coding            a3
  18.  
  19. ---------------------------------------------------------------------*/
  20.  
  21. /*    this is a generic set of routines to maintain a temporary
  22.     spool area to spool data and info blocks for incoming and
  23.     outgoing messages
  24. */
  25.  
  26. #ifndef __TYPES__
  27. #include <Types.h>
  28. #endif
  29.  
  30. #ifndef __FOLDERS__
  31. #include <Folders.h>
  32. #endif
  33.  
  34. #ifndef __ERRORS__
  35. #include <Errors.h>
  36. #endif
  37.  
  38. #ifndef __PACKAGES__
  39. #include <Packages.h>
  40. #endif
  41.  
  42. #ifndef __FILES__
  43. #include <Files.h>
  44. #endif
  45.  
  46. #ifdef applec
  47. #include <SysEqu.h>
  48. #endif
  49.  
  50. #include "const.h"
  51. #include "gwerrors.h"
  52. #include "globals.h"
  53. #include "mytypes.h"
  54. #include "utils.h"
  55. #include "spoolsystem.h"
  56.  
  57.  
  58. /* fsspec for root folder */
  59.  
  60. static FSSpec    gRootSpool;
  61.  
  62.  
  63. /* initialize spool stuff */
  64.  
  65. OSErr InitSpoolSubsystem(void)
  66. {
  67.     OSErr err;
  68.     long dirID;
  69.     short vRefNum;
  70.  
  71.     err = FindFolder(kOnSystemDisk,kTemporaryFolderType,true,&vRefNum,&dirID);
  72.  
  73.     if (err==noErr) {
  74.         pstrcpy(gRootSpool.name,kSpoolFolderName);
  75.         gRootSpool.parID = dirID;
  76.         gRootSpool.vRefNum = vRefNum;
  77.         err = FSpDirCreate(&gRootSpool,smSystemScript,&dirID);
  78.         if (err==dupFNErr) {
  79.             err = noErr;
  80.             RecursiveDeleteDirectory(gRootSpool.vRefNum,gRootSpool.parID,gRootSpool.name);
  81.             err = FSpDirCreate(&gRootSpool,smSystemScript,&dirID);
  82.         }
  83.     }
  84.                 
  85.     return err;
  86. }
  87.  
  88.  
  89. /* release spool subsystem by clearing spool database */
  90.  
  91. OSErr ExitSpoolSubsystem(void)
  92. {
  93.     OSErr err;
  94.  
  95.     err = RecursiveDeleteDirectory(gRootSpool.vRefNum,gRootSpool.parID,gRootSpool.name);
  96.     return err;
  97. }
  98.  
  99.  
  100. /* create a spool area on disk, and return it's FSSpec */
  101.  
  102. OSErr CreateSpoolFile(FSSpec *sFile)
  103. {
  104.     OSErr err;
  105.     long randNum;
  106.     Str255 randStr;
  107.     long dirID;
  108.  
  109. #ifdef __SYSEQU__
  110.     BlockMove((Ptr)TimeLM,(Ptr)RndSeed,sizeof(long));
  111. #else
  112.     RndSeed = Time;
  113. #endif
  114.  
  115.     randNum = (unsigned long) Random();
  116.     NumToString(randNum,randStr);
  117.     
  118.     err = GetFSSpecDirID(&gRootSpool,&dirID);
  119.     if (err!=noErr) {
  120.         return err;
  121.     }
  122.  
  123.     sFile->vRefNum = gRootSpool.vRefNum;
  124.     sFile->parID = dirID;
  125.     pstrcpy(sFile->name,"\pspool");
  126.     pstrcat(sFile->name,randStr);
  127.     
  128.     err = FSpDirCreate(sFile,smSystemScript,&dirID);
  129.     
  130.     return err;
  131. }
  132.  
  133.  
  134. /* remove a spool area from the disk, including any spool information contained within */
  135.  
  136. OSErr RemoveSpoolFile(FSSpec *sFile)
  137. {
  138.     OSErr err;
  139.     
  140.     err = RecursiveDeleteDirectory(sFile->vRefNum,sFile->parID,sFile->name);
  141.     return err;
  142. }
  143.  
  144.  
  145. /* spool a data block to the file, given a type, creator, ID, and the data with its length */
  146.  
  147. OSErr SpoolToFile(FSSpec *sFile,OSType type,OSType creator,long id,char *data,unsigned long dataLen)
  148. {
  149.     OSErr err;
  150.     FSSpec newSpec;
  151.     Str255 idStr;
  152.     short fRefNum;
  153.     long dirID;
  154.     char osTypeStr[5];
  155.     
  156.     NumToString(id,idStr);
  157.     
  158.     /* get dirID of parent */
  159.     
  160.     err = GetFSSpecDirID(sFile,&dirID);
  161.     if (err!=noErr) {
  162.         return err;
  163.     }
  164.     
  165.     /* make new spool datafile */
  166.     
  167.     newSpec.parID = dirID;
  168.     newSpec.vRefNum = sFile->vRefNum;
  169.     pstrcpy(newSpec.name,"\pdata");
  170.     pstrcat(newSpec.name,idStr);
  171.     osTypeStr[0] = 4;
  172.     BlockMove(&creator,&osTypeStr[1],4);
  173.     pstrcat(newSpec.name,osTypeStr);
  174.     BlockMove(&type,&osTypeStr[1],4);
  175.     pstrcat(newSpec.name,osTypeStr);
  176.     
  177.     err = FSpCreate(&newSpec,creator,type,smSystemScript);
  178.     if (err!=noErr) {
  179.         return err;
  180.     }
  181.     
  182.     /* write data out to file */
  183.     
  184.     err = FSpOpenDF(&newSpec,fsRdWrPerm,&fRefNum);
  185.     if (err!=noErr) {
  186.         return err;
  187.     }
  188.     err = FSWrite(fRefNum,(long *)&dataLen,data);
  189.     if (err!=noErr) {
  190.         FSClose(fRefNum);
  191.         return err;
  192.     }
  193.     err = FSClose(fRefNum);
  194.         
  195.     return err;
  196. }
  197.  
  198.  
  199. /* append additional info to a spool element */
  200.  
  201. OSErr AppendToSpool(FSSpec *sFile,OSType type,OSType creator,long id,char *data,unsigned long dataLen)
  202. {
  203.     OSErr err;
  204.     FSSpec newSpec;
  205.     Str255 idStr;
  206.     short fRefNum;
  207.     long dirID;
  208.     char osTypeStr[5];
  209.  
  210.     NumToString(id,idStr);
  211.     
  212.     /* get dirID of parent */
  213.     
  214.     err = GetFSSpecDirID(sFile,&dirID);
  215.     if (err!=noErr) {
  216.         return err;
  217.     }
  218.     
  219.     /* append data */
  220.     
  221.     newSpec.parID = dirID;
  222.     newSpec.vRefNum = sFile->vRefNum;
  223.     pstrcpy(newSpec.name,"\pdata");
  224.     pstrcat(newSpec.name,idStr);
  225.     osTypeStr[0] = 4;
  226.     BlockMove(&creator,&osTypeStr[1],4);
  227.     pstrcat(newSpec.name,osTypeStr);
  228.     BlockMove(&type,&osTypeStr[1],4);
  229.     pstrcat(newSpec.name,osTypeStr);
  230.  
  231.     err = FSpOpenDF(&newSpec,fsRdWrPerm,&fRefNum);
  232.     if (err!=noErr) {
  233.         return err;
  234.     }
  235.  
  236.     /* go to end of file */
  237.     
  238.     err = SetFPos(fRefNum,fsFromLEOF,0);
  239.     if (err!=noErr) {
  240.         FSClose(fRefNum);
  241.         return err;
  242.     }
  243.     
  244.     err = FSWrite(fRefNum,(long *)&dataLen,data);
  245.     if (err!=noErr) {
  246.         FSClose(fRefNum);
  247.         return err;
  248.     }
  249.     err = FSClose(fRefNum);
  250.         
  251.     return err;
  252. }
  253.  
  254.  
  255. /*    get info out of a spool element (max bytes *dataLen, returned bytes in
  256.     *dataLen, startOffset is offset from start of element */
  257.  
  258. OSErr GetFromSpool(FSSpec *sFile,OSType type,OSType creator,long id,char *data,
  259.                     unsigned long *dataLen,long startOffset)
  260. {
  261.     OSErr err;
  262.     FSSpec newSpec;
  263.     Str255 idStr;
  264.     short fRefNum;
  265.     long dirID;
  266.     char osTypeStr[5];
  267.     long testGet;
  268.     char testData[1];
  269.     
  270.     NumToString(id,idStr);
  271.     
  272.     /* get dirID of parent */
  273.     
  274.     err = GetFSSpecDirID(sFile,&dirID);
  275.     if (err!=noErr) {
  276.         return err;
  277.     }
  278.     
  279.     /* read data */
  280.     
  281.     newSpec.parID = dirID;
  282.     newSpec.vRefNum = sFile->vRefNum;
  283.     pstrcpy(newSpec.name,"\pdata");
  284.     pstrcat(newSpec.name,idStr);
  285.     osTypeStr[0] = 4;
  286.     BlockMove(&creator,&osTypeStr[1],4);
  287.     pstrcat(newSpec.name,osTypeStr);
  288.     BlockMove(&type,&osTypeStr[1],4);
  289.     pstrcat(newSpec.name,osTypeStr);
  290.  
  291.     err = FSpOpenDF(&newSpec,fsRdWrPerm,&fRefNum);
  292.     if (err!=noErr) {
  293.         return kNoData;
  294.     }
  295.  
  296.     /* go to spot in file */
  297.     
  298.     err = SetFPos(fRefNum,fsFromStart,startOffset);
  299.     if (err!=noErr) {
  300.         return err;
  301.     }
  302.     
  303.     /* read bytes */
  304.     
  305.     err = FSRead(fRefNum,(long*)dataLen,data);
  306.     if (err==noErr) {
  307.         testGet = 1;
  308.         err = FSRead(fRefNum,&testGet,testData);
  309.         if (err==noErr)
  310.             err = kMoreData;
  311.     }
  312.     
  313.     if (err==eofErr)
  314.         err = noErr;
  315.     if (err!=noErr) {
  316.         FSClose(fRefNum);
  317.         return err;
  318.     }
  319.     
  320.     err = FSClose(fRefNum);
  321.         
  322.     return err;
  323. }
  324.  
  325.  
  326. /* get the length of a spool element in bytes */
  327.  
  328. OSErr GetSpoolLength(FSSpec *sFile,OSType type,OSType creator,long id,unsigned long *dataLen)
  329. {
  330.     OSErr err;
  331.     Str255 idStr;
  332.     long dirID;
  333.     char osTypeStr[5];
  334.     CInfoPBRec infoRec;
  335.     Str31 fName;
  336.     
  337.     NumToString(id,idStr);
  338.     
  339.     /* get dirID of parent */
  340.     
  341.     err = GetFSSpecDirID(sFile,&dirID);
  342.     if (err!=noErr) {
  343.         return err;
  344.     }
  345.     
  346.     pstrcpy(fName,"\pdata");
  347.     pstrcat(fName,idStr);
  348.     osTypeStr[0] = 4;
  349.     BlockMove(&creator,&osTypeStr[1],4);
  350.     pstrcat(fName,osTypeStr);
  351.     BlockMove(&type,&osTypeStr[1],4);
  352.     pstrcat(fName,osTypeStr);
  353.     
  354.     infoRec.hFileInfo.ioNamePtr = fName;
  355.     infoRec.hFileInfo.ioVRefNum = sFile->vRefNum;
  356.     infoRec.hFileInfo.ioFDirIndex = 0;
  357.     infoRec.hFileInfo.ioDirID = dirID;
  358.     err = PBGetCatInfo(&infoRec,false);
  359.     *dataLen = infoRec.hFileInfo.ioFlLgLen;
  360.     if (err!=noErr)
  361.         err = kNoData;
  362.     return err;
  363. }
  364. /*---------------------*/
  365.  
  366. /* recursively delete a sub-tree */
  367.  
  368. OSErr RecursiveDeleteDirectory(short vRefNum,long dirID,StringPtr fName)
  369. {
  370.     OSErr err;
  371.     CInfoPBRec pBlock;
  372.     HParamBlockRec ourDelBlock;
  373.     Str255 ourNameStore;
  374.     
  375.     /* save our location for tail delete reference */
  376.     
  377.     BlockMove(fName,ourNameStore,sizeof(Str255));
  378.     ourDelBlock.ioParam.ioNamePtr = ourNameStore;
  379.     ourDelBlock.ioParam.ioVRefNum = vRefNum;
  380.     ourDelBlock.fileParam.ioDirID = dirID;
  381.         
  382.     /* delete children */
  383.     
  384.     pBlock.dirInfo.ioNamePtr = fName;
  385.     pBlock.dirInfo.ioVRefNum = vRefNum;
  386.     pBlock.hFileInfo.ioFVersNum = 0;
  387.     pBlock.dirInfo.ioFDirIndex = 0;
  388.     pBlock.dirInfo.ioDrDirID = dirID;
  389.     err = PBGetCatInfo(&pBlock,false);
  390.     if (err!=noErr)
  391.         return err;
  392.     dirID = pBlock.dirInfo.ioDrDirID;
  393.     
  394.     do {
  395.         pBlock.dirInfo.ioDrDirID = dirID;
  396.         pBlock.dirInfo.ioFDirIndex = 1;
  397.         err = PBGetCatInfo(&pBlock,false);
  398.         if (err==noErr) {
  399.             if ((pBlock.dirInfo.ioFlAttrib & 0x10) != 0)    // directory
  400.                 RecursiveDeleteDirectory(vRefNum,pBlock.dirInfo.ioDrDirID,fName);
  401.             else {
  402.                 pBlock.hFileInfo.ioDirID = pBlock.hFileInfo.ioFlParID;
  403.                 err = PBHDelete((HParmBlkPtr)&pBlock,false);
  404.             }
  405.         }
  406.     } while (err==noErr);
  407.         
  408.     /* delete ourselves */
  409.  
  410.     pBlock.dirInfo.ioNamePtr = fName;
  411.     pBlock.dirInfo.ioDrDirID = dirID;
  412.     pBlock.dirInfo.ioFDirIndex = -1;
  413.     pBlock.hFileInfo.ioFVersNum = 0;
  414.     err = PBGetCatInfo(&pBlock,false);
  415.     if (err==noErr) {
  416.         ourDelBlock.fileParam.ioDirID = pBlock.dirInfo.ioDrParID;
  417.         err = PBHDelete(&ourDelBlock,false);
  418.     }
  419.     return err;
  420. }
  421.  
  422.  
  423. /* get a directory's directory ID from it's FSSpec */
  424.  
  425. OSErr GetFSSpecDirID(FSSpec *fSpec,long *dirID)
  426. {
  427.     OSErr err;
  428.     CInfoPBRec pBlock;
  429.     
  430.     pBlock.dirInfo.ioNamePtr = fSpec->name;
  431.     pBlock.dirInfo.ioVRefNum = fSpec->vRefNum;
  432.     pBlock.dirInfo.ioDrDirID = fSpec->parID;
  433.     pBlock.dirInfo.ioFDirIndex = 0;
  434.     err = PBGetCatInfo(&pBlock,false);    
  435.     *dirID = pBlock.dirInfo.ioDrDirID;
  436.     return err;
  437. }
  438.